package com.xiaoc.bulldozer.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.xc.framework.cache.manager.CacheManager;
import com.xc.framework.cache.utils.CacheUtils;
import com.xc.framework.common.exception.BusinessException;
import com.xc.framework.common.thread.ThreadContext;
import com.xiaoc.bulldozer.common.CacheKeys;
import com.xiaoc.bulldozer.common.ConfigKeys;
import com.xiaoc.bulldozer.common.Constant;
import com.xiaoc.bulldozer.common.ResponseCode;
import com.xiaoc.bulldozer.common.dto.WeixinUserDto;
import com.xiaoc.bulldozer.common.model.Account;
import com.xiaoc.bulldozer.common.model.WeixinUser;
import com.xiaoc.bulldozer.common.service.AccountService;
import com.xiaoc.bulldozer.common.service.cache.CommonConfigCacheService;
import com.xiaoc.bulldozer.facade.WeixinUserFacade;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping(value = "/user/weixin")
public class WeixinUserController extends BulldozerFrontBaseController {

    private Logger logger = LoggerFactory.getLogger(WeixinUserController.class);

    @Autowired
    private WxMaService wxService;

    @Resource
    private WeixinUserFacade weixinUserFacade;

    @Resource(name = "commonConfigService")
    private CommonConfigCacheService commonConfigService;

    @Resource(name = "remoteCacheManager")
    private CacheManager remoteCacheManager;

    @Resource(name = "accountService")
    private AccountService accountService;

    /**
     * 登录接口
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ModelAndView login(@RequestBody WeixinUserDto weixinUserDto) {
        logger.info("login params : {}", weixinUserDto);
        String code = weixinUserDto.getCode();

        try {
            WxMaJscode2SessionResult session = this.wxService.getUserService().getSessionInfo(code);
            String openId = session.getOpenid();
            logger.info("openId:[{}], sessionKey: [{}]", session.getOpenid(), session.getSessionKey());
            synchronized (openId.intern()){
                weixinUserDto = weixinUserFacade.createWeixinUserDto(openId, session.getSessionKey());
            }
        } catch (Exception e) {
            logger.error("weixin user login failed, message :{}", e.getMessage(),  e);
            throw new BusinessException(ResponseCode.BUSINESS_ERROR.getCode(), "系统异常");
        }

        if (weixinUserDto == null || StringUtils.isEmpty(weixinUserDto.getSessionId())) {
            logger.error("login openId is null");
            throw new BusinessException(ResponseCode.BUSINESS_ERROR.getCode(), "请重新登录");
        }

        if (weixinUserDto.getParentUserId() != null) {
            remoteCacheManager.put(CacheUtils.generateCacheKey(CacheKeys.PARENT_USER_ID_KEY, weixinUserDto.getId()), weixinUserDto.getParentUserId(), Constant.PARENT_USER_ID_TIMEOUT);
        }
        Map<String, Object> paramMap = new HashMap<String, Object>(8);

        paramMap.put("userId", weixinUserDto.getId());
        paramMap.put("sessionId", weixinUserDto.getSessionId());
        paramMap.put("userType", weixinUserDto.getUserType());
        return renderLoginJson("common/login.json", paramMap);
    }

    @RequestMapping(value = "/proxyLogin", method = RequestMethod.POST)
    public ModelAndView proxyLogin(@RequestBody WeixinUserDto weixinUserDto) {

        String openId = weixinUserDto.getOpenId();
        String sessionId = weixinUserDto.getSessionId();

        String proxyOpenId = weixinUserDto.getProxyOpenId();

        if (StringUtils.isEmpty(proxyOpenId)) {
            logger.error("proxy login error");
            throw new BusinessException(ResponseCode.BUSINESS_ERROR.getCode(), "请求错误");
        }

        String proxyOpenIds = commonConfigService.getValue(ConfigKeys.PROXY_LOGIN_OPENIDS);
        //String proxyOpenIds = "qlksl";
        if (StringUtils.isEmpty(proxyOpenIds)) {
            logger.error("proxyOpenIds is null");
            throw new BusinessException(ResponseCode.BUSINESS_ERROR.getCode(), "请求错误");
        }

        String[] arry = StringUtils.split(proxyOpenIds, ",");
        if (arry == null || arry.length == 0) {
            logger.error("proxyOpenIds is empty");
            throw new BusinessException(ResponseCode.BUSINESS_ERROR.getCode(), "请求错误");
        }

        boolean isMatched = false;

        for (String proxy : arry) {
            if (StringUtils.equals(proxy, proxyOpenId)) {
                isMatched = true;
                break;
            }
        }

        if (!isMatched) {
            logger.error("proxyOpenId not matched openId:" + openId + ", proxyOpenId:" + proxyOpenId);
            throw new BusinessException(ResponseCode.BUSINESS_ERROR.getCode(), "请求错误");
        }

        WeixinUserDto existWeixinUserDto = weixinUserFacade.getWeixinUserDtoByOpenId(openId);
        weixinUserFacade.putWeixinUserDto(sessionId, existWeixinUserDto);

        ThreadContext.put(Constant.COOKIE_SESSION_ID, sessionId);
        return jsonSucess();
    }

    /**
     * 更新微信用户信息
     *
     * @param weixinUser
     */
    @RequestMapping(value = "/fill/info", method = RequestMethod.POST)
    public ModelAndView updateWeixinUser(@RequestBody WeixinUser weixinUser) {

        WeixinUserDto weixinUserDto = getCurrentWeixinUserDto();
        Account account = accountService.getAccountByUserId(weixinUserDto.getId());

        if (account != null) {
            account.setName(weixinUser.getNickName());
            account.setPhotoUrl(weixinUser.getAvatarUrl());
            accountService.update(account);
        }

        logger.info("info sessionKey{}",weixinUserDto.getSessionKey());
        weixinUserDto.setNickName(weixinUser.getNickName());
        weixinUserDto.setGender(weixinUser.getGender());
        weixinUserDto.setCity(weixinUser.getCity());
        weixinUserDto.setProvince(weixinUser.getProvince());
        weixinUserDto.setCountry(weixinUser.getCountry());
        weixinUserDto.setAvatarUrl(weixinUser.getAvatarUrl());


        if (StringUtils.isEmpty(weixinUserDto.getAvatarUrl())) {
            weixinUserDto.setAvatarUrl(commonConfigService.getValue(ConfigKeys.DEFAULT_WX_HEADER_URL));
        }

        if (StringUtils.isEmpty(weixinUserDto.getNickName())) {
            weixinUserDto.setNickName(Constant.DEFAULT_WX_NICKNAME);
        }

        weixinUserFacade.updateWeixinUserInfo(weixinUserDto);
        return jsonSucess();
    }

    /**
     * 更新微信用户地理位置
     */
    @RequestMapping(value = "/fill/address", method = RequestMethod.POST)
    public ModelAndView fillAddress(@RequestBody WeixinUser weixinUser) {

        if (StringUtils.isBlank(weixinUser.getLocationAddress())) {
            return jsonFailed(ResponseCode.BUSINESS_ERROR.getCode(), ResponseCode.BUSINESS_ERROR.getMsg());
        }

        WeixinUserDto weixinUserDto = getCurrentWeixinUserDto();

        weixinUserDto.setLocationAddress(weixinUser.getLocationAddress());
        //weixinUserDto.setLocationCity(locationCity);

        logger.info("微信定位地址：{}", weixinUserDto.getLocationAddress());

        weixinUserFacade.updateWeixinUserAddress(weixinUserDto);
        return jsonSucess();
    }

}
